In diesem Tutorial beschreibe ich die Benutzung von BLOBs (Binary Large Objects),


Direkt vorweg, ich bin kein Freund, kein Befürworter von großen Binärdaten in einer Datenbank.

Es ist meistens sinnvoller diese auf dem Filesystem zu belassen und in der DB nur einen Verweis darauf zu speichern.


Nun aber los.

Als erstes Verbinden wir uns wieder mit der Datenbank,


@INCLUDE "PostgreSQL_Lib.hws"


Block        

       Local Fail, fields, SQL$, i, a, f$

       Local Errorcode, BrushID

       Local Host$ = "localhost"

       Local Port = 5432

       Local Database$ = "postgres"

       Local Username$ = "test"

       Local Passwort$ = "test"

       Local Bind = {}

       Local Bind1 = {}

       Local Result = {}

       

       ;registration

       Fail, ErrorCode, ConnectionID = PG:OpenDatabase(Host$, Port, Database$, Username$, Passwort$)

       

       ; Evaluating the Return values

       If Fail = False 

               NPrint("")

               NPrint("Connection was successfully established.")

               NPrint("----------------------------------------")

       Else

               NPrint("")

               NPrint("The connection failed.")

               NPrint("")

               NPrint("Error code:  ", ErrorCode)

               End

       EndIf





Nun laden wir ein Bild, welches wir später in die Datenbank schreiben.


        ;Load an image file

       f$ = FileToString("picture.png")




Als nächstes erstellen wir eine Tabelle mit folgenden Spalten:


Tabelle Personen:

Vorname

Typ: text

Name

Typ: text

Alter

Typ: int4

Bild

Typ: bytea


Beachten Sie bitte: PostgreSQL benötigt zum speichern von BLOBs eine Spalte vom Typ bytea.


       ;Create a new table

       Local SQL$ = "CREATE TABLE Personen (Vorname text, Name text, Alter int4, Bild bytea)"

       Fail, Errorcode = PG:SimpleUpdate(SQL$, ConnectionID)        

       ; Evaluating the Return values

       If Fail = False 

               NPrint("")

               NPrint("Table was created.")

               NPrint("")

               NPrint("")

       Else

               NPrint("")

               NPrint("Create Table failed.")

               NPrint("")

               NPrint("Error code:  ", ErrorCode)

       EndIf




Nun werden wir der Tabelle eine Zeile hinzufügen.

Neu im Code unten ist die Bindungsvariable 4 vom Typ #BLOB.

Der String enthält das komplette Bild in Form von Raw-Data.


       ;Create binding variables

       InsertItem(Bind, #STRING);SQL variable $1

       InsertItem(Bind, "Michael")

       InsertItem(Bind, #STRING);SQL variable $2

       InsertItem(Bind, "Mustermann")

       InsertItem(Bind, #INTEGER);SQL variable $3

       InsertItem(Bind, 48)

       InsertItem(Bind, #BLOB)        ;SQL variable $4

       InsertItem(Bind, f$)

       

       

       ;Write data To the table

       SQL$ = "INSERT INTO Personen VALUES ($1, $2, $3, $4)"

       Fail, Errorcode = PG:ExtendedUpdate(Bind, SQL$, ConnectionID)

       If Fail = False

               NPrint("Database update successful")

               NPrint("")

               NPrint("")

       Else

               NPrint("INSERT INTO Personen failed.")

               NPrint("Error code:  ", ErrorCode)

       EndIf




Nun lesen wir die gesamte Zeile wieder aus der Datenbank.

Wie immer enthält die Tabelle "Result" alle Daten der Zeile wie Vorname, Name, Alter und natürlich auch das Bild.


       ;Read data from the database

       SQL$ = "SELECT * FROM Personen;"

       Fail, Errorcode, fields, Result = PG:SimpleQuery(SQL$, ConnectionID)

       If Fail = False

               NPrint("")

               NPrint("Data read successfully")

               NPrint("")

       Else

               NPrint("Query failed.")

               NPrint("Error code:  ", ErrorCode)

       EndIf




Der nun folgende Code bedarf wieder etwas Erklärung.

PostgreSQL sendet das BLOB leider in einem eigenen Format, welches zu validen Binärdaten konvertiert werden muss.

Diese Aufgabe erledigt die Funktion PG:ConvertBLOB.


Im Beispiel unten  übergeben wir der Funktion folgende Ausdrücke:

  • Der erste Ausdruck (fields) besagt die Anzahl der Spalten.
  • Der zweite Ausdruck (column) besagt in welcher Spalte sich das BLOB befindet (beginnend mit 0).
  • Der dritte Ausdruck (Result) enthält natürlich die Daten die wir vorhin empfangen haben.


Sollten Sie einmal Tabellen mit mehreren BYTEA-Spalten haben, müssen sie PG:ConvertBLOB für jede Spalte Separat ausführen.


       ;Convert the BLOB data into a usable format

       Fail, ErrorCode, Result = PG:ConvertBLOB(fields, 3, Result)

       If Fail = False

               NPrint("")

               NPrint("BLOB conversion successful")

               NPrint("")

       Else

               NPrint("ConvertBLOB failed")

               NPrint("Error code:  ", ErrorCode)

       EndIf




Nachdem wir das BLOB erfolgreich ins Originalformat konvertiert haben speichern wir es auf der Festplatte.

Aber unter einem anderen Namen, damit wir überprüfen können ob das Bild die Transfers fehlerfrei überstanden hat.


       ;Save image To hard disk

       StringToFile(Result[3], "test.png")




Als letztes lassen wir uns die gesamten Daten anzeigen und löschen die Tabelle wieder.


       ;Show the whole record

       BrushID = LoadBrush(Nil, "test.png")

       NPrint("")

       NPrint("Vorname : ", Result[0])

       NPrint("Name    : ", Result[1])

       NPrint("Alter   : ", Result[2])

       DisplayBrush(BrushID, 20,180, {Width = 100, Height = 100})


       

       ;Delete the table

       SQL$ = "DROP TABLE Personen;"

       Fail, Errorcode = PG:SimpleUpdate(SQL$, ConnectionID)

       ; Evaluating the Return values

       If Fail = False 

               Locate(0,350)

               NPrint("Table has been deleted")

       Else

               NPrint("DROP table failed.")

               NPrint("Error code:  ", ErrorCode)

       EndIf

       

       WaitLeftMouse        

       

       ;Close connection To the database.

       PG:CloseDatabase(ConnectionID)



EndBlock

 



Die Programmausgabe sollte dann so aussehen:




Das Tutorial sowie mein Kunstwerk "picture.png" befindet sich natürlich auch im Archiv.




Mit dem Personal Edition von HelpNDoc erstellt: Kindle eBooks mit Leichtigkeit generieren